﻿using UnityEngine;
using System;
using UnityEngine.UI;
using DG.Tweening;
using Random = UnityEngine.Random;

namespace HareGame
{
    public partial class Util
    {
        /// <summary>
        /// 缩放(带遮照)
        /// </summary>
        /// <param name="imgMask">遮照</param>
        /// <param name="transBg">背景</param>
        /// <param name="fade">透明度</param>
        public Sequence DoScaleWithMask(Image imgMask, Transform transBg, float fade = 0.8f)
        {
            imgMask.DOKill();
            imgMask.DOFade(0, 0).SetUpdate(true);
            imgMask.DOFade(fade, 0.26f).SetEase(Ease.Linear).SetUpdate(true);
            return DoScale(transBg);
        }

        /// <summary>
        /// 缩放
        /// </summary>
        /// <param name="transBg">背景</param>
        public Sequence DoScale(Transform transBg)
        {
            transBg.gameObject.GetOrAddComponent<CanvasGroup>().DOFade(1, 0).SetUpdate(true);
            transBg.DOKill();
            transBg.DOScale(0, 0).SetUpdate(true);

            Sequence anim = DOTween.Sequence();
            anim.SetDelay(0.01f)
                .Append(transBg.DOScale(1.1f, 0.25f).SetEase(Ease.OutQuad))
                .SetDelay(0.01f)
                .Append(transBg.DOScale(0.96f, 0.3f).SetEase(Ease.InOutQuad))
                .SetDelay(0.01f)
                .Append(transBg.DOScale(1f, 0.2f).SetEase(Ease.OutQuad))
                .Play()
                .SetUpdate(true);
            return anim;
        }

        /// <summary>
        /// 隐藏(带遮照)
        /// </summary>
        /// <param name="imgMask">遮照</param>
        /// <param name="transBg">背景</param>
        public Tweener DoHideWithMask(Image imgMask, Transform transBg)
        {
            imgMask.DOKill();
            imgMask.DOFade(0, 0.25f).SetEase(Ease.Linear).SetUpdate(true);
            return DoHide(transBg);
        }

        /// <summary>
        /// 隐藏
        /// </summary>
        /// <param name="transBg">背景</param>
        public Tweener DoHide(Transform transBg)
        {
            transBg.gameObject.GetOrAddComponent<CanvasGroup>().DOFade(0, 0.25f).SetUpdate(true);
            return transBg.DOScale(0, 0.25f).SetEase(Ease.InOutQuad).SetUpdate(true);
        }

        /// <summary>
        /// 向上弹出(带遮照)
        /// </summary>
        /// <param name="imgMask">遮照</param>
        /// <param name="transBg">背景</param>
        /// <param name="fade">透明度</param>
        public Sequence DoMoveUpWithMask(Image imgMask, Transform transBg, float fade = 0.4f)
        {
            imgMask.DOKill();
            imgMask.DOFade(0, 0).SetUpdate(true);
            imgMask.DOFade(fade, 0.26f).SetEase(Ease.Linear).SetUpdate(true);
            return DoMoveUp(transBg);
        }

        /// <summary>
        /// 向上弹出
        /// </summary>
        /// <param name="transBg">背景</param>
        public Sequence DoMoveUp(Transform transBg)
        {
            transBg.gameObject.GetOrAddComponent<CanvasGroup>().DOFade(1, 0).SetUpdate(true);
            transBg.DOKill();
            float posY = -(Screen.height + transBg.GetComponent<RectTransform>().sizeDelta.y) / 2;
            transBg.localPosition = new Vector3(0, posY, 0);

            Sequence anim = DOTween.Sequence();
            anim.SetDelay(0.01f)
                .Append(transBg.DOLocalMoveY(30f, 0.25f).SetEase(Ease.OutQuad))
                .SetDelay(0.01f)
                .Append(transBg.DOLocalMoveY(-12f, 0.3f).SetEase(Ease.InOutQuad))
                .SetDelay(0.01f)
                .Append(transBg.DOLocalMoveY(0, 0.2f).SetEase(Ease.OutQuad))
                .Play()
                .SetUpdate(true);
            return anim;
        }

        /// <summary>
        /// 向上弹出返回动画(带遮照)
        /// </summary>
        /// <param name="imgMask">遮照</param>
        /// <param name="transBg">背景</param>
        public Tweener DoMoveUpBackWithMask(Image imgMask, Transform transBg)
        {
            imgMask.DOKill();
            imgMask.DOFade(0, 0.25f).SetEase(Ease.Linear).SetUpdate(true);
            return DoMoveUpBack(transBg);
        }

        /// <summary>
        /// 向上弹出返回动画
        /// </summary>
        /// <param name="transBg">背景</param>
        public Tweener DoMoveUpBack(Transform transBg)
        {
            transBg.gameObject.GetOrAddComponent<CanvasGroup>().DOFade(0, 0.25f).SetUpdate(true);
            float posY = -(Screen.height + transBg.GetComponent<RectTransform>().sizeDelta.y) / 2;
            return transBg.DOLocalMoveY(posY, 0.25f).SetEase(Ease.InOutQuad).SetUpdate(true);
        }

        /// <summary>
        /// 显示奖励动画
        /// </summary>
        /// <param name="assetName">资源名</param>
        /// <param name="target">目标</param>
        /// <param name="callback">回调</param>
        /// <param name="needBounce">是否需要Bounce动画</param>
        /// <param name="objNum">创建数量</param>
        public void DoRewardAnim(string assetName, Transform target, Action callback = null, bool needBounce = true, int objNum = 30)
        {
            for (int i = 0; i < objNum; i++)
            {
                int index = i;
                PoolObj obj = GameEntry.Pool.CreateObj<PoolObj>(assetName, GameEntry.UI.GetUIRoot().transform);
                obj.transform.localScale = Vector3.one;
                obj.transform.localPosition = Vector3.zero;
                obj.transform.DOLocalMove(new Vector3(Random.Range(-400f, 400f), Random.Range(-300f, 300f), 0), 0.6f)
                    .SetEase(Ease.OutCirc)
                    .SetUpdate(true)
                    .OnComplete(() =>
                    {
                        obj.transform.SetParent(target.parent);
                        obj.transform.DOLocalMove(target.localPosition, 1f)
                        .SetEase(Ease.InBack)
                        .SetUpdate(true)
                        .SetDelay(0.01f * index)
                        .OnComplete(() =>
                        {
                            if (index == 0)
                            {
                                callback?.Invoke();
                                GameEntry.Event.Send(EventID.RefreshDataUI);
                            }

                            if (needBounce)
                            {
                                obj.transform.DOScale(0f, 1f).SetEase(Ease.Linear).SetUpdate(true);
                                DoBounce(index, obj);
                            }
                            else
                            {
                                obj.RecycleSelf();
                            }
                        });
                    });
            }

            void DoBounce(int index, PoolObj obj, int loopTimes = 4)
            {
                if (loopTimes >= 0)
                {
                    obj.transform.DOLocalMove(target.localPosition + new Vector3(Random.Range(-20f, 20f), Random.Range(-20f, 20f), 0) * loopTimes, 0.075f * (loopTimes + 1))
                          .SetEase(Ease.InOutBounce)
                          .SetUpdate(true)
                          .OnComplete(() =>
                          {
                              DoBounce(index, obj, loopTimes);
                          });
                    loopTimes--;
                }
                else
                {
                    obj.RecycleSelf();
                }
            }
        }
    }
}